package com.sc.nft.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.AdminMallShareTeamOrderPageDTO;
import com.sc.nft.entity.dto.MallShareTeamOrderPageDTO;
import com.sc.nft.entity.dto.TeamOrderDTO;
import com.sc.nft.entity.vo.AdminMallShareTeamOrderPageVO;
import com.sc.nft.entity.vo.MallShareTeamOrderPageVO;
import com.sc.nft.enums.*;
import com.sc.nft.enums.wallet.MallDaoWalletTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.util.BigDecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 分享购团队订单 服务实现类
 * </p>
 *
 * @author ligen
 * @since 2023-12-13
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class MallShareTeamOrderServiceImpl implements MallShareTeamOrderService {

    private final MallShareTeamOrderDao mallShareTeamOrderDao;
    private final MallActivityShareService mallActivityShareService;
    private final MallActivityShareTeamService mallActivityShareTeamService;
    private final UserWalletDao userWalletDao;
    private final UserWalletDetailDao userWalletDetailDao;
    private final ExpenditureRecordDao expenditureRecordDao;
    private final UserInfoDao userInfoDao;
    private final MallDaoWalletService mallDaoWalletService;
    private final StaticDataDao staticDataDao;
    @Autowired
    MallOrderRefundService mallOrderRefundService;

    /**
     * 成团订单列表
     *
     * @param adminMallShareTeamOrderPageVO
     * @return
     */
    @Override
    public Page<AdminMallShareTeamOrderPageDTO> getAdminMallShareTeamOrderPageDTO(AdminMallShareTeamOrderPageVO adminMallShareTeamOrderPageVO) {
        return mallShareTeamOrderDao.getAdminMallShareTeamOrderPageDTO(adminMallShareTeamOrderPageVO.getPageNo(), adminMallShareTeamOrderPageVO.getPageSize(), adminMallShareTeamOrderPageVO.getTeamId());
    }

    /**
     * 用户端拼团订单列表
     *
     * @param mallShareTeamOrderPageVO
     * @return
     */
    @Override
    public Page<MallShareTeamOrderPageDTO> getMallShareTeamOrderPageDTO(MallShareTeamOrderPageVO mallShareTeamOrderPageVO) {
        return mallShareTeamOrderDao.getMallShareTeamOrderPageDTO(mallShareTeamOrderPageVO.getPageNo(), mallShareTeamOrderPageVO.getPageSize(), mallShareTeamOrderPageVO.getTeamId());
    }

    /**
     * 创建成团订单
     *
     * @param activityShareTeamId 分享购团队ID
     * @param mallOrder
     */
    @Override
    public void create(Long activityShareTeamId, MallOrder mallOrder) {
        try {
            MallActivityShareTeam mallActivityShareTeam = mallActivityShareTeamService.getById(activityShareTeamId);
            MallActivityShare mallActivityShare = mallActivityShareService.getById(mallActivityShareTeam.getActivityShareId());
            if (DateTime.now().before(mallActivityShareTeam.getEndTime())) {
                // 在成团有效期之内
                BigDecimal realPrice = mallOrder.getRealPrice();
                BigDecimal headIncome = realPrice.multiply(mallActivityShare.getRewardPercentage());
                MallShareTeamOrder mallShareTeamOrder = new MallShareTeamOrder();
                mallShareTeamOrder.setActivityShareTeamId(activityShareTeamId);
                mallShareTeamOrder.setOrderId(mallOrder.getId());
                UserInfo userInfo = userInfoDao.getById(mallOrder.getUserId());
                mallShareTeamOrder.setOrderUserTel(userInfo.getUserTel());
                mallShareTeamOrder.setHeadIncome(headIncome);
                // 创建是默认可以发放收益 实际发放需要看收益时间
                mallShareTeamOrder.setIsCanIssue(Boolean.TRUE);
                mallShareTeamOrder.setIsIssue(Boolean.FALSE);
                mallShareTeamOrder.insert();
                mallActivityShareTeamService.addOrderNumById(activityShareTeamId, 1);
            }
        } catch (Exception e) {
            log.error("创建成团订单异常:{}", e.getMessage());
        }
    }

    /**
     * 获取订单的分享团订单信息
     *
     * @param shareTeamId
     * @param orderId
     * @return
     */
    @Override
    public MallShareTeamOrder getByOrderId(Long shareTeamId, Long orderId) {
        return mallShareTeamOrderDao.getByOrderId(shareTeamId, orderId);
    }

    /**
     * 获取是否可以发收益的成团订单
     *
     * @param isCanIssue
     * @return
     */
    @Override
    public List<MallShareTeamOrder> getTeamOrderByIsCanIssue(Long teamId, Boolean isCanIssue) {
        return mallShareTeamOrderDao.getTeamOrderByIsCanIssue(teamId, isCanIssue);
    }

    /**
     * 分享活动团队收益结算
     *
     * @param mallActivityShareTeam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void shareTeamIncomeSettlement(MallActivityShareTeam mallActivityShareTeam) {
        if (ShareTeamStatusEnum.GROUPING_IN_PROGRESS == mallActivityShareTeam.getStatus()) {
            Date now = new Date();
            // 拼团中的团队才能结算收益
            List<TeamOrderDTO> teamOrderDTOList = mallShareTeamOrderDao.getTeamOrderDTO(mallActivityShareTeam.getId());
            if (CollectionUtils.isEmpty(teamOrderDTOList)) {
                // 无有效订单
                // 拼团失败
                mallActivityShareTeamService.updateStatus(mallActivityShareTeam.getId(), ShareTeamStatusEnum.GROUPING_FAILURE);
                return;
            }
            List<TeamOrderDTO> finishList = teamOrderDTOList.stream().filter(teamOrderDTO -> MallOrderStatusEnum.FINISH == teamOrderDTO.getOrderStatus() && DateUtil.offsetDay(teamOrderDTO.getFinishTime(), 7).before(now)).collect(Collectors.toList());
            if (finishList.size() < teamOrderDTOList.size()) {
                return;
            }
            // 查询拼团订单的售后单
            List<MallOrderRefund> refundServiceListByTeamOrder = mallOrderRefundService.getListByTeamOrder(mallActivityShareTeam.getId());
            List<MallOrderRefund> notSuccessList = refundServiceListByTeamOrder.stream().filter(mallOrderRefund -> MallRefundStatusEnum.afterSalesStatusList().contains(mallOrderRefund.getRefundStatus())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(notSuccessList)) {
                return;
            }
            if (mallActivityShareTeam.getIsCanIssue()) {
                // 拼团成功
                List<MallShareTeamOrder> teamOrderByIsCanIssue = getTeamOrderByIsCanIssue(mallActivityShareTeam.getId(), Boolean.TRUE);
                // 团长总收益
                BigDecimal totalHeadIncome = teamOrderByIsCanIssue.stream().map(MallShareTeamOrder::getHeadIncome).reduce(BigDecimal.ZERO, BigDecimal::add);
                List<Long> teamOrderIds = teamOrderByIsCanIssue.stream().map(mallShareTeamOrder -> mallShareTeamOrder.getId()).collect(Collectors.toList());
                mallShareTeamOrderDao.updateIsIssue(teamOrderIds, true, now);
                mallActivityShareTeamService.updateStatus(mallActivityShareTeam.getId(), ShareTeamStatusEnum.GROUP_SUCCESSFULLY);
                //加钱
                UserWallet userWallet = userWalletDao.getByUserId(mallActivityShareTeam.getUserId());
                Assert.isTrue(userWalletDao.addIncome(mallActivityShareTeam.getUserId(), totalHeadIncome), ()->new GlobalRunTimeException(ErrorCode.FAILED_TO_ADD_MONEY));
                // 减去钱
                // 查询出NONO商城ID
                String noNoDaoId = staticDataDao.getByType("noNo_dao_id").getValue();
                mallDaoWalletService.subBalance(Long.valueOf(noNoDaoId),totalHeadIncome,BigDecimal.ZERO, MallDaoWalletTypeEnum.HEAD_INCOME_RELEASE,MallDaoWalletTypeEnum.HEAD_INCOME_RELEASE.getDescription());
                UserWalletDetail userWalletDetail = new UserWalletDetail();
                userWalletDetail.setUserId(mallActivityShareTeam.getUserId());
                userWalletDetail.setType(WalletDetailTypeEnum.SHARE_GROUP_REWARDS);
                userWalletDetail.setAmount(totalHeadIncome);
                userWalletDetail.setCharge(BigDecimal.ZERO);
                userWalletDetail.setRealAmount(totalHeadIncome);
                userWalletDetail.setAfterBalance(userWallet.getBalance().add(totalHeadIncome));
                userWalletDetail.setBeforeBalance(userWallet.getBalance());
                userWalletDetail.setIdentityNo(StrUtil.EMPTY);
                userWalletDetail.setIsAdd(Boolean.TRUE);
                userWalletDetail.setPhone(StrUtil.EMPTY);
                userWalletDetail.setRemark(StrUtil.EMPTY);
                userWalletDetail.setCardNo(StrUtil.EMPTY);
                userWalletDetail.setBankName(StrUtil.EMPTY);
                userWalletDetail.setName(StrUtil.EMPTY);
                userWalletDetail.setBalanceType(UserBalanceTypeEnum.BALANCE);
                userWalletDetailDao.insert(userWalletDetail);

                ExpenditureRecord expenditureRecord = new ExpenditureRecord();
                expenditureRecord.setUserId(mallActivityShareTeam.getUserId());
                expenditureRecord.setAmount(totalHeadIncome);
                expenditureRecord.setCharge(BigDecimal.ZERO);
                expenditureRecord.setRealAmount(totalHeadIncome);
                expenditureRecord.setType(ExpenditureRecordTypeEnum.SHARE_GROUP_REWARDS);
                expenditureRecord.setBeforeBalance(userWallet.getBalance());
                expenditureRecord.setAfterBalance(userWallet.getBalance().add(totalHeadIncome));
                expenditureRecord.setRemark("");
                expenditureRecordDao.insert(expenditureRecord);
            } else {
                // 拼团失败
                mallActivityShareTeamService.updateStatus(mallActivityShareTeam.getId(), ShareTeamStatusEnum.GROUPING_FAILURE);
            }
        }
    }
}
